esp32 arduino 移植lvgl,oled显示,lvgl屏幕建立,屏幕切换,图片显示,手动发送事件,触发部件响应其对应的回调函数,label,bar,line,style简单使用,显示字体修改

您所在的位置:网站首页 arduino oled 菜单 esp32 arduino 移植lvgl,oled显示,lvgl屏幕建立,屏幕切换,图片显示,手动发送事件,触发部件响应其对应的回调函数,label,bar,line,style简单使用,显示字体修改

esp32 arduino 移植lvgl,oled显示,lvgl屏幕建立,屏幕切换,图片显示,手动发送事件,触发部件响应其对应的回调函数,label,bar,line,style简单使用,显示字体修改

2024-04-22 01:48| 来源: 网络整理| 查看: 265

屏幕采用的是128*64的分辨率的OLED,驱动ic应该是SSD1306,这个刚好支持129*64的,但是就是单色屏,用的是IIC接口

1,OLED设置:

管脚配置如下:

SSD1306Wire display(0x3c, 4, 15);//实例化OLED显示,设置管脚,该方法输入参数:uint8_t _address, uint8_t _sda, uint8_t _scl

由于我的OLED的库没有清除像素点的函数,而在lvgl的显示驱动函数中,需要设置一下,基于OLED显示的lvgl移植的关键点之一就是将LVGL的显示接口与

OLED的显示接口对应,在显示驱动函数中实现。所以我在源库文件(OLEDDisplay.cpp)里添加了像素点清除函数如下所示:当然在OLEDDisplay.h声明也少不了,就不贴代码啦。

void OLEDDisplay::clearPixel(int16_t x, int16_t y) { if (x >= 0 && x < 128 && y >= 0 && y < 64) { switch (color) { case WHITE: buffer[x + (y / 8) * DISPLAY_WIDTH] &= ~(1 LVGL - Light and Versatile Graphics Library

LVGL provides everything you need to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint.

Website · Live demo · Docs · Forum · Blog --- - [Features](#features) - [Supported devices](#supported-devices) - [Quick start in a simulator](#quick-start-in-a-simulator) - [Add LVGL to your project](#add-lvgl-to-your-project) - [Learn the basics](#learn-the-basics) - [Examples](#examples) - [Release policy](#release-policy) - [Contributing](#contributing) ## Features * **Powerful building blocks** buttons, charts, lists, sliders, images, etc. * **Advanced graphics** with animations, anti-aliasing, opacity, smooth scrolling * **Simultaneously use various input devices** touchscreen, mouse, keyboard, encoder, buttons, etc. * **Simultaneously use multiple displays** i.e. monochrome and color display * **Multi-language support** with UTF-8 encoding, Bidirectional support, and Arabic text handling * **Fully customizable** graphical elements * **Hardware independent** to use with any microcontroller or display * **Scalable** to operate with little memory (64 kB Flash, 10 kB RAM) * **OS, External memory and GPU** supported but not required * **Single frame buffer** operation even with advances graphical effects * **Written in C** for maximal compatibility (C++ compatible) * **Micropython Binding** exposes [LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings) * **Simulator** to develop on PC without embedded hardware * **Tutorials, examples, themes** for rapid development * **Documentation** and API references ## Supported devices Basically, every modern controller (which is able to drive a display) is suitable to run LVGL. The minimal requirements are: - 16, 32 or 64 bit microcontroller or processor - ; 16 MHz clock speed is recommended - Flash/ROM: ; 64 kB for the very essential components (; 180 kB is recommended) - RAM: - Static RAM usage: ~2 kB depending on the used features and objects types - Stack: ; 2kB (; 8 kB is recommended) - Dynamic data (heap): ; 2 KB (; 16 kB is recommended if using several objects). Set by `LV_MEM_SIZE` in *lv_conf.h*. - Display buffer: ; *"Horizontal resolution"* pixels (; 10 × *"Horizontal resolution"* is recommended) - C99 or newer compiler *Note that the memory usage might vary depending on the architecture, compiler and build options.* Just to mention some **platforms**: - STM32F1, STM32F3, [STM32F4](https://blog.lvgl.io/2017-07-15/stm32f429_disco_port), [STM32F7](https://github.com/lvgl/lv_port_stm32f746_disco_sw4stm32) - Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ - NXP Kinetis, LPC, iMX - [Linux frame buffer](https://blog.lvgl.io/2018-01-03/linux_fb) (/dev/fb) - [Raspberry PI](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl) - [Espressif ESP32](https://github.com/lvgl/lv_port_esp32) - Nordic nrf52 - Quectell M66 ## Quick start in a simulator The easiest way to get started with LVGL is to run it in a simulator on your PC without any embedded hardware. Choose a project with your favourite IDE: | Eclipse | CodeBlocks | Visual Studio | PlatformIO | Qt Creator | |-------------|-------------|---------------|-----------|------------| | [![Eclipse](https://raw.githubusercontent.com/lvgl/docs/master/v7/misc//eclipse.jpg)](https://github.com/lvgl/lv_sim_eclipse_sdl) | [![CodeBlocks](https://raw.githubusercontent.com/lvgl/docs/master/v7/misc//codeblocks.jpg)](https://github.com/lvgl/lv_sim_codeblocks_win) | [![VisualStudio](https://raw.githubusercontent.com/lvgl/docs/master/v7/misc//visualstudio.jpg)](https://github.com/lvgl/lv_sim_visual_studio_sdl) | [![PlatformIO](https://raw.githubusercontent.com/lvgl/docs/master/v7/misc//platformio.jpg)](https://github.com/lvgl/lv_platformio) | [![QtCreator](https://raw.githubusercontent.com/lvgl/docs/master/v7/misc//qtcreator.jpg)](https://blog.lvgl.io/2019-01-03/qt-creator) | | Cross-platformwith SDL(Recommended onLinux and Mac) | Native Windows | Windowswith SDL | Cross-platformwith SDL | Cross-platformwith SDL | ## Add LVGL to your project The steps below show how to setup LVGL on an embedded system with a display and a touchpad. You can use the [Simulators](https://docs.lvgl.io/v7/en/html/get-started/pc-simulator) to get ready to use projects which can be run on your PC. 1. [Download](https://github.com/lvgl/lvgl/archive/master.zip) or [Clone](https://github.com/lvgl/lvgl) the library 2. Copy the `lvgl` folder into your project 3. Copy `lvgl/lv_conf_template.h` as `lv_conf.h` next to the `lvgl` folder, change the `#if 0` statement near the top of the file to `#if 1` and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`. 4. Include `lvgl/lvgl.h` where you need to use LVGL related functions. 5. Call `lv_tick_inc(x)` every `x` milliseconds (should be 1..10) in a Timer or Task. It is required for the internal timing of LVGL. 6. Call `lv_init()` 7. Create a display buffer for LVGL ```c static lv_disp_buf_t disp_buf; static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/ lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/ ``` 8. Implement and register a function which can copy a pixel array to an area of your display: ```c lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ lv_disp_drv_init(&disp_drv); /*Basic initialization*/ disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/ disp_drv.buffer = &disp_buf; /*Assign the buffer to the display*/ lv_disp_drv_register(&disp_drv); /*Finally register the driver*/ void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p) { int32_t x, y; for(y = area->y1; y y2; y++) { for(x = area->x1; x x2; x++) { my_set_pixel(x, y, *color_p); /* Put a pixel to the display.*/ color_p++; } } lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/ } ``` 9. Implement and register a function which can read an input device. E.g. for a touch pad: ```c lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/ indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/ indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/ lv_indev_drv_register(&indev_drv); /*Finally register the driver*/ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { data->state = my_touchpad_is_pressed() ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&data->point.x, &data->point.y); return false; /*Return `false` because we are not buffering and no more data to read*/ } ``` 10. Call `lv_task_handler()` periodically every few milliseconds in the main `while(1)` loop, in Timer interrupt or in an Operation system task. It will redraw the screen if required, handle input devices etc. For more detailed desription visit the [Porting](https://docs.lvgl.io/v7/en/html/porting/index.html) section of the documentation. ## Learn the basics In this section you can read the very basics of LVGL. For a more detailed guide check the [Quick overview](https://docs.lvgl.io/v7/en/html/get-started/quick-overview.html#learn-the-basics) in the documentation. ### Widgets (Objects) The graphical elements like Buttons, Labels, Sliders, Charts etc are called objects or widgets in LVGL. Go to [Widgets](https://docs.lvgl.io/v7/en/html/widgets/index) to see the full list of available types. Every object has a parent object. The child object moves with the parent and if you delete the parent the children will be deleted too. Children can be visible only on their parent. The *screen* are the "root" parents. To get the current screen call `lv_scr_act()`. You can create a new object with `lv__create(parent, obj_to_copy)`. It will return an `lv_obj_t *` variable which should be used as a reference to the object to set its parameters later. The first parameter is the desired *parent*, the second parameters can be an object to copy (`NULL` if unused). For example: ```c lv_obj_t * slider1 = lv_slider_create(lv_scr_act(), NULL); ``` To set some basic attribute `lv_obj_set_(obj, )` function can be used. For example: ```c lv_obj_set_x(btn1, 30); lv_obj_set_y(btn1, 10); lv_obj_set_size(btn1, 200, 50); ``` The objects have type specific parameters too which can be set by `lv__set_(obj, )` functions. For example: ```c lv_slider_set_value(slider1, 70, LV_ANIM_ON); ``` To see the full API visit the documentation of the object types or the related header file (e.g. `lvgl/src/lv_objx/lv_slider.h`). To create a new screen pass `NULL` as the fisrt paramater of a *create* function: ```c lv_obj_t * scr2 = lv_obj_create(NULL, NULL); /*Create a screen*/ lv_scr_load(scr2); /*Load the new screen*/ ``` ### Styles Widgets are created with a default appearance but it can be changed by adding new styles to them. A new style can be created like this: ```c static lv_style_t style1; /*Should be static, global or dynamically allocated*/ lv_style_init(&style1); lv_style_set_bg_color(&style1, LV_STATE_DEFAULT, LV_COLOR_RED); /*Default background color*/ lv_style_set_bg_color(&style1, LV_STATE_PRESSED, LV_COLOR_BLUE); /*Pressed background color*/ ``` The wigedt have *parts* which can be referenced via `LV__PART_`. E.g. `LV_BTN_PART_MAIN` or `LV_SLIDER_PART_KNOB`. See the documentation of the widgets to see the exisitng parts. To add the style to a button: ```c lv_obj_add_style(btn1, LV_BTN_PART_MAIN, &style1); ``` To remove all styles from a part of an object: ```cc lv_obj_reset_style_list(obj, LV_OBJ_PART_MAIN); ``` Learn more in [Style overview](https://docs.lvgl.io/v7/en/html/overview/style) section. ### Events Events are used to inform the user if something has happened with an object. You can assign a callback to an object which will be called if the object is clicked, released, dragged, being deleted etc. It should look like this: ```c lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/ ... void btn_event_cb(lv_obj_t * btn, lv_event_t event) { if(event == LV_EVENT_CLICKED) { printf("Clicked\n"); } } ``` Learn more about the events in the [Event overview](https://docs.lvgl.io/v7/en/html/overview/event) section. ## Examples ### Button with label ```c lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button the current screen*/ lv_obj_set_pos(btn, 10, 10); /*Set its position*/ lv_obj_set_size(btn, 100, 50); /*Set its size*/ lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/ lv_obj_t * label = lv_label_create(btn, NULL); /*Add a label to the button*/ lv_label_set_text(label, "Button"); /*Set the labels text*/ ... void btn_event_cb(lv_obj_t * btn, lv_event_t event) { if(event == LV_EVENT_CLICKED) { printf("Clicked\n"); } } ``` ![LVGL button with label example](https://docs.lvgl.io/v7/en/misc/simple_button_example.gif) ### Use LVGL from Micropython Learn more about [Micropython](https://docs.lvgl.io/en/html/get-started/micropython). ```python # Create a Button and a Label scr = lv.obj() btn = lv.btn(scr) btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0) label = lv.label(btn) label.set_text("Button") # Load the screen lv.scr_load(scr) ``` ## Release policy LVGL follows the rules of [Semantic versioning](https://semver.org/): - Major versions for incompatible API changes. E.g. v5.0.0, v6.0.0 - Minor version for new but backward-compatible functionalities. E.g. v6.1.0, v6.2.0 - Patch version for backward-compatible bug fixes. E.g. v6.1.1, v6.1.2 Branches: - `master` most recent version, patches are merged directly here. - `dev` merge new features here until they are merged into `master`. - `release/vX` there is a branch for every major version to allow adding specific, not forward compatible fixes. LVGL has a monthly periodic release cycle. - **1st Tuesday of the month**   - Make a major, minor, or patch release from `master` depending on the new features.   - After that merge only patches into `master` and add new features into the `dev`. - **3rd Tuesday of the month**   - Make a patch release from `master`.   - After that merge the new features from the `dev` to `master` branch.   - In the rest of the month merge only patches into `master` and new features into `dev` branch. ## Contributing To ask questions please use the [Forum](https://forum.lvgl.io). For development-related things (bug reports, feature suggestions) use [GitHub's Issue tracker](https://github.com/lvgl/lvgl/issues). If you are interested in contributing to LVGL you can - **Help others** in the [Forum](https://forum.lvgl.io). - **Inspire people** by speaking about your project in [My project](https://forum.lvgl.io/c/my-projects) category in the Forum. - **Improve and/or translate the documentation.** Go to the [Documentation](https://github.com/lvgl/docs) repository to learn more - **Write a blog post** about your experiences. See how to do it in the [Blog](https://github.com/lvgl/blog) repository - **Report and/or fix bugs** in [GitHub's issue tracker](https://github.com/lvgl/lvgl/issues) - **Help in the developement**. Check the [Open issues](https://github.com/lvgl/lvgl/issues) especially the ones with [Help wanted](https://github.com/lvgl/lvgl/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) label and tell your ideas about a topic or implement a feature. Before sending Pull requests, please read the following guides: - [Contributing guide](https://github.com/lvgl/lvgl/blob/master/docs/CONTRIBUTING.md) - [Coding style guide](https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md)

在## Add LVGL to your project栏详细介绍了移植过程,部分过程解读:

步骤3:配置lv_conf.h文件说明LV_HOR_RES_MAX 和 LV_HOR_RES_MAX 宏的值,这个是告诉 littleVGL 你所用的液晶屏分辨率是多少,请根据自己手头液晶屏的实际分辨率大小相应设置

LV_COLOR_DEPTH 颜色深度,最常见的设置就是 1 或者 16 了,1 是用于单色屏,而 16 是用于彩色屏,这里我设置成1,因为我用的OLED是单色屏

LV_DPI 的值,默认值为 130(我的库默认是这个),把他设置到100,这个宏是用来调节界面缩放比例的,此值越大,控件分布的就越散,控件自身的间隔也会变大

LV_MEM_SIZE 的大小,这个就是控制 littleVGL 中所谓的动态数据堆的大小,是用来给控件的创建动态分配空间的,我这里设置为 32KB 的大小

当要使能某种字体时,找到对应的字体定义,设置为1,例如:#define LV_FONT_MONTSERRAT_12    1

LV_USE_FILESYSTEM 的值,其默认值为 1,使能文件系统的功能 ,(might be required for images )

接着可以设置 LV_THEME_LIVE_UPDATE, LV_USE_THEME_TEMPL,LV_USE_THEME_DEFAULT,LV_USE_THEME_ALIEN, LV_USE_THEME_NIGHT, LV_USE_THEME_MONO,LV_USE_THEME_MATERIAL, LV_USE_THEME_ZEN, LV_USE_THEME_NEMO 等宏的值为 1,即使能,这些宏都是跟 littleVGL自带的主题相关的,1表示使能对应主题,

注意,在实际项目中,我们一般最多使能一个,如果我们项目根本就用不到其自带的主题,那么我们应该把这些宏全部禁止,因为这样可以节省 flash 和 ram

步骤5:littleVGL 提供心跳节拍 的函数:lv_tick_inc参考lv_conf.h的这段代码

/* 1: use a custom tick source. * It removes the need to manually update the tick with `lv_tick_inc`) */ #define LV_TICK_CUSTOM 1 #if LV_TICK_CUSTOM == 1 #define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ #endif /*LV_TICK_CUSTOM*/

所以,其实在esp32 arduino中,不需要调用这个函数,但是在比如stm32等看别人是用定时器定时调用的。

步骤8:配置显示,这里是移植的关键点,就是对应lvgl与OLED的接口,代码参考如下,显示驱动函数,在这里可知道上面定义的OLED像素点清除函数的作用了:

/* Display flushing 1.把指定区域的显示缓冲区内容写入到屏幕上,你可以使用DMA或者其他的硬件加速器在后台去完成这个操作 2.但是在完成之后,你必须得调用lv_disp_flush_ready() 3.移植lvgl到对应屏幕上,需要对应lvgl的接口与显示的接口,在这里设置 4.littleVGL 支持 4 种颜色深度,格式分为为 1 byte per pixel, RGB233, RGB565, ARGB8888,其对应的配置项值分别为 1, 8, 16, 32,在一般的实际项目中,最常用的为 1 和 16,当然如果你 的处理器性能和资源都很高的话,那么你可以选择 32,占用 4 个字节,他会给你的项目带来更逼真的颜色效果,保证不失真,如果你选择的是 1,那么它只支持 2 种颜色,占用 1 个字节,在液晶 屏上的表现就是显示与不显示的关系,常用于单色屏,比如 lcd12864,oled 等,当你选择的是 16时,那么他支持 65536 种颜色,占用 2 个字节,显示效果还是很不错的,同时对处理器的要求也不 是很高,因此 16 成为了我们实际项目中最常用的设置值.Display flushing函数中lv_color_t* color_p变量传递回来的就是显示区第要显示的点的颜色值地址 */ void my_disp_flush(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) { /*获取显示区的宽度与高度*/ uint32_t w = (area->x2 - area->x1 + 1); uint32_t h = (area->y2 - area->y1 + 1); /*刷新显示区每个点的像素值*/ for (uint16_t y = area->y1; y y2; y++){ for (uint16_t x = area->x1; x x2; x++){ if(color_p->full != 0)display.setPixel(x, y);//由于我是用的OLED只有黑白,所以配置的2种颜色,当颜色值为1时设置该像素点 else display.clearPixel(x, y);//由于我是用的OLED只有黑白,所以配置的2种颜色,当颜色值为0时设置清除像素点 color_p++; } } display.display();//刷新OLED显示 lv_disp_flush_ready(disp);/* Indicate you are ready with the flushing 最后必须得调用,通知 lvgl 库你已经 flushing 拷贝完成了*/ }

步骤9:由于我还没有外部输入,所以这里就没有配置

lvgl简介:

littleVGL 可以说是这 2 年才刚开始流行的一个小型开源嵌入式 GUI 库,具有界面精美,消耗资源小,可移植度高,响应式布局等特点,全库采用纯 c 语言开发,

littleVGL 的主要特性如下:• 具有非常丰富的内置控件,像 buttons, charts, lists, sliders, images 等• 高级图形效果:动画,反锯齿,透明度,平滑滚动• 支持多种输入设备,像 touchpad, mouse, keyboard, encoder 等• 支持多语言的 UTF-8 编码• 支持多个和多种显示设备,例如同步显示在多个彩色屏或单色屏上• 完全自定制的图形元素• 硬件独立于任何微控制器或显示器• 可以缩小到最小内存 (64 kB Flash, 16 kB RAM)• 支持操作系统、外部储存和 GPU(非必须)• 仅仅单个帧缓冲设备就可以呈现高级视觉特效• 使用 C 编写以获得最大兼容性(兼容 C++)• 支持 PC 模拟器• 为加速 GUI 设计,提供教程,案例和主题,支持响应式布局• 提供了在线和离线文档• 基于自由和开源的 MIT 协议

littleVGL 的要求如下:• 16、 32 或 64 位的单片机(微控制器)或处理器• 微处理器的主频最好高于 16MHZ• Flash/ROM:如果只用 littleVGL 核心组件的话,则至少需要 64kB 的容量,如果想完整使用的话,最好保证 180kB 以上的容量• RAM:    o 静态 RAM: 大约 8 到 16 kB,这取决于你所用的组件功能和 objects 控件对象类型    o 栈: 至少为 2Kb,一般推荐值为 4kB

    o 动态数据(堆): 至少 4kB,如果你用到了多个或多种控件的话,那么最好设置为 16kB 以上,这个是可以通过 lv_conf.h 配置文件中的 LV_MEM_SIZE 宏来定义的    o 显示缓冲区: 至少要比”水平分辨率像素”要大,一般推介值为 10 倍的”水平分辨率素”,取个例子,假如我们屏幕的水平分辨率为480个像素,采用16位的颜色深度进行显示,即一个像素占 2 个字节,那么推介的显示缓冲区大小为 10*480*2=9600 个字节• C99 或更新的编译器,如果是用 keil 开发的话,一定得勾选”c99”模式,否则编译会报错的• 基本的



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3